home *** CD-ROM | disk | FTP | other *** search
/ Cream of the Crop 26 / Cream of the Crop 26.iso / program / ddj0897.zip / RCSC.ZIP / PACKAGES / SC22.ZIP / CC3.C < prev    next >
C/C++ Source or Header  |  1988-01-25  |  22KB  |  753 lines

  1. /*
  2. ** Small-C Compiler -- Part 3 -- Expression Analyzer.
  3. ** Copyright 1982, 1983, 1985, 1988 J. E. Hendrix
  4. ** All rights reserved.
  5. */
  6.  
  7. #include <stdio.h>
  8. #include "cc.h"
  9.  
  10. #define ST 0   /* is[ST] - symbol table address, else 0 */
  11. #define TI 1   /* is[TI] - type of indirect obj to fetch, else 0 */
  12. #define TA 2   /* is[TA] - type of address, else 0 */
  13. #define TC 3   /* is[TC] - type of constant (INT or UINT), else 0 */
  14. #define CV 4   /* is[CV] - value of constant (+ auxiliary uses) */
  15. #define OP 5   /* is[OP] - code of highest/last binary operator */
  16. #define SA 6   /* is[SA] - stage address of "op 0" code, else 0 */
  17.  
  18. extern char
  19.  *litq, *glbptr, *lptr,  ssname[NAMESIZE],  quote[2];
  20. extern int
  21.   ch,  csp,  litlab,  litptr,  nch,  op[16],  op2[16],
  22.   opindex,  opsize, *snext;
  23.  
  24. /***************** lead-in functions *******************/
  25.  
  26. constexpr(val) int *val; {
  27.   int const;
  28.   int *before, *start;
  29.   setstage(&before, &start);
  30.   expression(&const, val);
  31.   clearstage(before, 0);     /* scratch generated code */
  32.   if(const == 0) error("must be constant expression");
  33.   return const;
  34.   }
  35.  
  36. expression(con, val) int *con, *val;  {
  37.   int is[7];
  38.   if(level1(is)) fetch(is);
  39.   *con = is[TC];
  40.   *val = is[CV];
  41.   }
  42.  
  43. test(label, parens)  int label, parens;  {
  44.   int is[7];
  45.   int *before, *start;
  46.   if(parens) need("(");
  47.   while(1) {
  48.     setstage(&before, &start);
  49.     if(level1(is)) fetch(is);
  50.     if(match(",")) clearstage(before, start);
  51.     else break;
  52.     }
  53.   if(parens) need(")");
  54.   if(is[TC]) {             /* constant expression */
  55.     clearstage(before, 0);
  56.     if(is[CV]) return;
  57.     gen(JMPm, label);
  58.     return;
  59.     }
  60.   if(is[SA]) {             /* stage address of "oper 0" code */
  61.     switch(is[OP]) {       /* operator code */
  62.       case EQ12:
  63.       case LE12u: zerojump(EQ10f, label, is); break;
  64.       case NE12:
  65.       case GT12u: zerojump(NE10f, label, is); break;
  66.       case GT12:  zerojump(GT10f, label, is); break;
  67.       case GE12:  zerojump(GE10f, label, is); break;
  68.       case GE12u: clearstage(is[SA], 0);      break;
  69.       case LT12:  zerojump(LT10f, label, is); break;
  70.       case LT12u: zerojump(JMPm,  label, is); break;
  71.       case LE12:  zerojump(LE10f, label, is); break;
  72.       default:    gen(NE10f, label);          break;
  73.       }
  74.     }
  75.   else gen(NE10f, label);
  76.   clearstage(before, start);
  77.   }
  78.  
  79. /*
  80. ** test primary register against zero and jump if false
  81. */
  82. zerojump(oper, label, is) int oper, label, is[]; {
  83.   clearstage(is[SA], 0);       /* purge conventional code */
  84.   gen(oper, label);
  85.   }
  86.  
  87. /***************** precedence levels ******************/
  88.  
  89. level1(is) int is[];  {
  90.   int k, is2[7], is3[2], oper, oper2;
  91.   k = down1(level2, is);
  92.   if(is[TC]) gen(GETw1n, is[CV]);
  93.        if(match("|="))  {oper =        oper2 = OR12;}
  94.   else if(match("^="))  {oper =        oper2 = XOR12;}
  95.   else if(match("&="))  {oper =        oper2 = AND12;}
  96.   else if(match("+="))  {oper =        oper2 = ADD12;}
  97.   else if(match("-="))  {oper =        oper2 = SUB12;}
  98.   else if(match("*="))  {oper = MUL12; oper2 = MUL12u;}
  99.   else if(match("/="))  {oper = DIV12; oper2 = DIV12u;}
  100.   else if(match("%="))  {oper = MOD12; oper2 = MOD12u;}
  101.   else if(match(">>=")) {oper =        oper2 = ASR12;}
  102.   else if(match("<<=")) {oper =        oper2 = ASL12;}
  103.   else if(match("="))   {oper =        oper2 = 0;}
  104.   else return k;
  105.                         /* have an assignment operator */
  106.   if(k == 0) {
  107.     needlval();
  108.     return 0;
  109.     }
  110.   is3[ST] = is[ST];
  111.   is3[TI] = is[TI];
  112.   if(is[TI]) {                             /* indirect target */
  113.     if(oper) {                             /* ?= */
  114.       gen(PUSH1, 0);                       /* save address */
  115.       fetch(is);                           /* fetch left side */
  116.       }
  117.     down2(oper, oper2, level1, is, is2);   /* parse right side */
  118.     if(oper) gen(POP2, 0);                 /* retrieve address */
  119.     }
  120.   else {                                   /* direct target */
  121.     if(oper) {                             /* ?= */
  122.       fetch(is);                           /* fetch left side */
  123.       down2(oper, oper2, level1, is, is2); /* parse right side */
  124.       }
  125.     else {                                 /*  = */
  126.       if(level1(is2)) fetch(is2);          /* parse right side */
  127.       }
  128.     }
  129.   store(is3);                              /* store result */
  130.   return 0;
  131.   }
  132.  
  133. level2(is1)  int is1[]; {
  134.   int is2[7], is3[7], k, flab, endlab, *before, *after;
  135.   k = down1(level3, is1);                   /* expression 1 */
  136.   if(match("?") == 0) return k;
  137.   dropout(k, NE10f, flab = getlabel(), is1);
  138.   if(down1(level2, is2)) fetch(is2);        /* expression 2 */
  139.   else if(is2[TC]) gen(GETw1n, is2[CV]);
  140.   need(":");
  141.   gen(JMPm, endlab = getlabel());
  142.   gen(LABm, flab);
  143.   if(down1(level2, is3)) fetch(is3);        /* expression 3 */
  144.   else if(is3[TC]) gen(GETw1n, is3[CV]);
  145.   gen(LABm, endlab);
  146.  
  147.   is1[TC] = is1[CV] = 0;
  148.   if(is2[TC] && is3[TC]) {                  /* expr1 ? const2 : const3 */
  149.     is1[TA] = is1[TI] = is1[SA] = 0;
  150.     }
  151.   else if(is3[TC]) {                        /* expr1 ? var2 : const3 */
  152.     is1[TA] = is2[TA];
  153.     is1[TI] = is2[TI];
  154.     is1[SA] = is2[SA];
  155.     }
  156.   else if((is2[TC])                         /* expr1 ? const2 : var3 */
  157.        || (is2[TA] == is3[TA])) {           /* expr1 ? same2 : same3 */
  158.     is1[TA] = is3[TA];
  159.     is1[TI] = is3[TI];
  160.     is1[SA] = is3[SA];
  161.     }
  162.   else error("mismatched expressions");
  163.   return 0;
  164.   }
  165.  
  166. level3 (is) int is[]; {return skim("||", EQ10f, 1, 0, level4,  is);}
  167. level4 (is) int is[]; {return skim("&&", NE10f, 0, 1, level5,  is);}
  168. level5 (is) int is[]; {return down("|",            0, level6,  is);}
  169. level6 (is) int is[]; {return down("^",            1, level7,  is);}
  170. level7 (is) int is[]; {return down("&",            2, level8,  is);}
  171. level8 (is) int is[]; {return down("== !=",        3, level9,  is);}
  172. level9 (is) int is[]; {return down("<= >= < >",    5, level10, is);}
  173. level10(is) int is[]; {return down(">> <<",        9, level11, is);}
  174. level11(is) int is[]; {return down("+ -",         11, level12, is);}
  175. level12(is) int is[]; {return down("* / %",       13, level13, is);}
  176.  
  177. level13(is)  int is[];  {
  178.   int k;
  179.   char *ptr;
  180.   if(match("++")) {                 /* ++lval */
  181.     if(level13(is) == 0) {
  182.       needlval();
  183.       return 0;
  184.       }
  185.     step(rINC1, is, 0);
  186.     return 0;
  187.     }
  188.   else if(match("--")) {            /* --lval */
  189.     if(level13(is) == 0) {
  190.       needlval();
  191.       return 0;
  192.       }
  193.     step(rDEC1, is, 0);
  194.     return 0;
  195.     }
  196.   else if(match("~")) {             /* ~ */
  197.     if(level13(is)) fetch(is);
  198.     gen(COM1, 0);
  199.     is[CV] = ~ is[CV];
  200.     return (is[SA] = 0);
  201.     }
  202.   else if(match("!")) {             /* ! */
  203.     if(level13(is)) fetch(is);
  204.     gen(LNEG1, 0);
  205.     is[CV] = ! is[CV];
  206.     return (is[SA] = 0);
  207.     }
  208.   else if(match("-")) {             /* unary - */
  209.     if(level13(is)) fetch(is);
  210.     gen(ANEG1, 0);
  211.     is[CV] = -is[CV];
  212.     return (is[SA] = 0);
  213.     }
  214.   else if(match("*")) {             /* unary * */
  215.     if(level13(is)) fetch(is);
  216.     if(ptr = is[ST]) is[TI] = ptr[TYPE];
  217.     else             is[TI] = INT;
  218.     is[SA] =       /* no (op 0) stage address */
  219.     is[TA] =       /* not an address */
  220.     is[TC] = 0;    /* not a constant */
  221.     is[CV] = 1;    /* omit fetch() on func call */
  222.     return 1;
  223.     }
  224.   else if(amatch("sizeof", 6)) {    /* sizeof() */
  225.     int sz, p;  char *ptr, sname[NAMESIZE];
  226.     if(match("(")) p = 1;
  227.     else           p = 0;
  228.     sz = 0;
  229.     if     (amatch("unsigned", 8))  sz = BPW;
  230.     if     (amatch("int",      3))  sz = BPW;
  231.     else if(amatch("char",     4))  sz = 1;
  232.     if(sz) {if(match("*"))          sz = BPW;}
  233.     else if(symname(sname)
  234.          && ((ptr = findloc(sname)) ||
  235.              (ptr = findglb(sname)))
  236.          && ptr[IDENT] != FUNCTION
  237.          && ptr[IDENT] != LABEL)    sz = getint(ptr+SIZE, 2);
  238.     else if(sz == 0) error("must be object or type");
  239.     if(p) need(")");
  240.     is[TC] = INT;
  241.     is[CV] = sz;
  242.     is[TA] = is[TI] = is[ST] = 0;
  243.     return 0;
  244.     }
  245.   else if(match("&")) {             /* unary & */
  246.     if(level13(is) == 0) {
  247.       error("illegal address");
  248.       return 0;
  249.       }
  250.     ptr = is[ST];
  251.     is[TA] = ptr[TYPE];
  252.     if(is[TI]) return 0;
  253.     gen(POINT1m, ptr);
  254.     is[TI] = ptr[TYPE];
  255.     return 0;
  256.     }
  257.   else {
  258.     k = level14(is);
  259.     if(match("++")) {               /* lval++ */
  260.       if(k == 0) {
  261.         needlval();
  262.         return 0;
  263.         }
  264.       step(rINC1, is, rDEC1);
  265.       return 0;
  266.       }
  267.     else if(match("--")) {          /* lval-- */
  268.       if(k == 0) {
  269.         needlval();
  270.         return 0;
  271.         }
  272.       step(rDEC1, is, rINC1);
  273.       return 0;
  274.       }
  275.     else return k;
  276.     }
  277.   }
  278.  
  279. level14(is)  int *is; {
  280.   int k, const, val;
  281.   char *ptr, *before, *start;
  282.   k = primary(is);
  283.   ptr = is[ST];
  284.   blanks();
  285.   if(ch == '[' || ch == '(') {
  286.     int is2[7];                     /* allocate only if needed */
  287.     while(1) {
  288.       if(match("[")) {              /* [subscript] */
  289.         if(ptr == 0) {
  290.           error("can't subscript");
  291.           skip();
  292.           need("]");
  293.           return 0;
  294.           }
  295.         if(is[TA]) {if(k) fetch(is);}
  296.         else       {error("can't subscript"); k = 0;}
  297.         setstage(&before, &start);
  298.         is2[TC] = 0;
  299.         down2(0, 0, level1, is2, is2);
  300.         need("]");
  301.         if(is2[TC]) {
  302.           clearstage(before, 0);
  303.           if(is2[CV]) {             /* only add if non-zero */
  304.             if(ptr[TYPE] >> 2 == BPW)
  305.                  gen(GETw2n, is2[CV] << LBPW);
  306.             else gen(GETw2n, is2[CV]);
  307.             gen(ADD12, 0);
  308.             }
  309.           }
  310.         else {
  311.           if(ptr[TYPE] >> 2 == BPW) gen(DBL1, 0);
  312.           gen(ADD12, 0);
  313.           }
  314.         is[TA] = 0;
  315.         is[TI] = ptr[TYPE];
  316.         k = 1;
  317.         }
  318.       else if(match("(")) {         /* function(...) */
  319.         if(ptr == 0) callfunc(0);
  320.         else if(ptr[IDENT] != FUNCTION) {
  321.           if(k && !is[CV]) fetch(is);
  322.           callfunc(0);
  323.           }
  324.         else callfunc(ptr);
  325.         k = is[ST] = is[TC] = is[CV] = 0;
  326.         }
  327.       else return k;
  328.       }
  329.     }
  330.   if(ptr && ptr[IDENT] == FUNCTION) {
  331.     gen(POINT1m, ptr);
  332.     is[ST] = 0;
  333.     return 0;
  334.     }
  335.   return k;
  336.   }
  337.  
  338. primary(is)  int *is; {
  339.   char *ptr, sname[NAMESIZE];
  340.   int k;
  341.   if(match("(")) {                  /* (subexpression) */ 
  342.     do k = level1(is); while(match(","));
  343.     need(")");
  344.     return k;
  345.     }
  346.   putint(0, is, 7 << LBPW);         /* clear "is" array */
  347.   if(symname(sname)) {              /* is legal symbol */
  348.     if(ptr = findloc(sname)) {      /* is local */
  349.       if(ptr[IDENT] == LABEL) {
  350.         experr();
  351.         return 0;
  352.         }
  353.       gen(POINT1s, getint(ptr+OFFSET, 2));
  354.       is[ST] = ptr;
  355.       is[TI] = ptr[TYPE];
  356.       if(ptr[IDENT] == ARRAY) {
  357.         is[TA] = ptr[TYPE];
  358.         return 0;
  359.         }
  360.       if(ptr[IDENT] == POINTER) {
  361.         is[TI] = UINT;
  362.         is[TA] = ptr[TYPE];
  363.         }
  364.       return 1;
  365.       }
  366.     if(ptr = findglb(sname)) {      /* is global */
  367.       is[ST] = ptr;
  368.       if(ptr[IDENT] != FUNCTION) {
  369.         if(ptr[IDENT] == ARRAY) {
  370.           gen(POINT1m, ptr);
  371.           is[TI] = 
  372.           is[TA] = ptr[TYPE];
  373.           return 0;
  374.           }
  375.         if(ptr[IDENT] == POINTER)
  376.           is[TA] = ptr[TYPE];
  377.         return 1;
  378.         }
  379.       }
  380.     else is[ST] = addsym(sname, FUNCTION, INT, 0, 0, &glbptr, AUTOEXT);
  381.     return 0;
  382.     }
  383.   if(constant(is) == 0) experr();
  384.   return 0;
  385.   }
  386.  
  387. experr() {
  388.   error("invalid expression");
  389.   gen(GETw1n, 0);
  390.   skip();
  391.   }
  392.  
  393. callfunc(ptr)  char *ptr; {      /* symbol table entry or 0 */
  394.   int nargs, const, val;
  395.   nargs = 0;
  396.   blanks();                      /* already saw open paren */
  397.   while(streq(lptr, ")") == 0) {
  398.     if(endst()) break;
  399.     if(ptr) {
  400.       expression(&const, &val);
  401.       gen(PUSH1, 0);
  402.       }
  403.     else {
  404.       gen(PUSH1, 0);
  405.       expression(&const, &val);
  406.       gen(SWAP1s, 0);            /* don't push addr */
  407.       }
  408.     nargs = nargs + BPW;         /* count args*BPW */
  409.     if(match(",") == 0) break;
  410.     }
  411.   need(")");
  412.   if(streq(ptr + NAME, "CCARGC") == 0) gen(ARGCNTn, nargs >> LBPW);
  413.   if(ptr) gen(CALLm, ptr);
  414.   else    gen(CALL1, 0);
  415.   gen(ADDSP, csp + nargs);
  416.   }
  417.  
  418. /*
  419. ** true if is2's operand should be doubled
  420. */
  421. double(oper, is1, is2) int oper, is1[], is2[]; {
  422.   if((oper != ADD12 && oper != SUB12)
  423.   || (is1[TA] >> 2 != BPW)
  424.   || (is2[TA])) return 0;
  425.   return 1;
  426.   }
  427.  
  428. step(oper, is, oper2) int oper, is[], oper2; {
  429.   fetch(is);
  430.   gen(oper, is[TA] ? (is[TA] >> 2) : 1);
  431.   store(is);
  432.   if(oper2) gen(oper2, is[TA] ? (is[TA] >> 2) : 1);
  433.   }
  434.  
  435. store(is)  int is[]; {
  436.   char *ptr;
  437.   if(is[TI]) {                    /* putstk */
  438.     if(is[TI] >> 2 == 1)
  439.          gen(PUTbp1, 0);
  440.     else gen(PUTwp1, 0);
  441.     }
  442.   else {                          /* putmem */
  443.     ptr = is[ST];
  444.     if(ptr[IDENT] != POINTER
  445.     && ptr[TYPE] >> 2 == 1)
  446.          gen(PUTbm1, ptr);
  447.     else gen(PUTwm1, ptr);
  448.     }
  449.   }
  450.  
  451. fetch(is) int is[]; {
  452.   char *ptr;
  453.   ptr = is[ST];
  454.   if(is[TI]) {                                   /* indirect */
  455.     if(is[TI] >> 2 == BPW)     gen(GETw1p,  0);
  456.     else {
  457.       if(ptr[TYPE] & UNSIGNED) gen(GETb1pu, 0);
  458.       else                     gen(GETb1p,  0);
  459.       }
  460.     } 
  461.   else {                                         /* direct */
  462.     if(ptr[IDENT] == POINTER
  463.     || ptr[TYPE] >> 2 == BPW)  gen(GETw1m,  ptr); 
  464.     else {
  465.       if(ptr[TYPE] & UNSIGNED) gen(GETb1mu, ptr);
  466.       else                     gen(GETb1m,  ptr);
  467.       }
  468.     }
  469.   }
  470.  
  471. constant(is)  int is[]; {
  472.   int offset;
  473.   if     (is[TC] = number(is + CV)) gen(GETw1n,  is[CV]);
  474.   else if(is[TC] = chrcon(is + CV)) gen(GETw1n,  is[CV]);
  475.   else if(string(&offset))          gen(POINT1l, offset);
  476.   else return 0;
  477.   return 1;
  478.   }
  479.  
  480. number(value)  int *value; {
  481.   int k, minus;
  482.   k = minus = 0;
  483.   while(1) {
  484.     if(match("+")) ;
  485.     else if(match("-")) minus = 1;
  486.     else break;
  487.     }
  488.   if(isdigit(ch) == 0) return 0;
  489.   if(ch == '0') {
  490.     while(ch == '0') inbyte();
  491.     if(toupper(ch) == 'X') {
  492.       inbyte();
  493.       while(isxdigit(ch)) {
  494.         if(isdigit(ch))
  495.              k = k*16 + (inbyte() - '0');
  496.         else k = k*16 + 10 + (toupper(inbyte()) - 'A');
  497.         }
  498.       }
  499.     else while (ch >= '0' && ch <= '7')
  500.       k = k*8 + (inbyte() - '0');
  501.     }
  502.   else while (isdigit(ch)) k = k*10 + (inbyte() - '0');
  503.   if(minus) {
  504.     *value = -k;
  505.     return (INT);
  506.     }
  507.   if((*value = k) < 0) return (UINT);
  508.   else                 return (INT);
  509.   }
  510.  
  511. chrcon(value)  int *value; {
  512.   int k;
  513.   k = 0;
  514.   if(match("'") == 0) return 0;
  515.   while(ch != '\'') k = (k << 8) + (litchar() & 255);
  516.   gch();
  517.   *value = k;
  518.   return (INT);
  519.   }
  520.  
  521. string(offset) int *offset; {
  522.   char c;
  523.   if(match(quote) == 0) return 0;
  524.   *offset = litptr;
  525.   while (ch != '"') {
  526.     if(ch == 0) break;
  527.     stowlit(litchar(), 1);
  528.     }
  529.   gch();
  530.   litq[litptr++] = 0;
  531.   return 1;
  532.   }
  533.  
  534. stowlit(value, size) int value, size; {
  535.   if((litptr+size) >= LITMAX) {
  536.     error("literal queue overflow");
  537.     abort(ERRCODE);
  538.     }
  539.   putint(value, litq+litptr, size);
  540.   litptr += size;
  541.   }
  542.  
  543. litchar() {
  544.   int i, oct;
  545.   if(ch != '\\' || nch == 0) return gch();
  546.   gch();
  547.   switch(ch) {
  548.     case 'n': gch(); return NEWLINE;
  549.     case 't': gch(); return  9;  /* HT */
  550.     case 'b': gch(); return  8;  /* BS */
  551.     case 'f': gch(); return 12;  /* FF */
  552.     }
  553.   i = 3;
  554.   oct = 0;
  555.   while((i--) > 0 && ch >= '0' && ch <= '7')
  556.     oct = (oct << 3) + gch() - '0';
  557.   if(i == 2) return gch();
  558.   else       return oct;
  559.   }
  560.  
  561. /***************** pipeline functions ******************/
  562.  
  563. /*
  564. ** skim over terms adjoining || and && operators
  565. */
  566. skim(opstr, tcode, dropval, endval, level, is)
  567.   char *opstr;
  568.   int tcode, dropval, endval, (*level)(), is[]; {
  569.   int k, droplab, endlab;
  570.   droplab = 0;
  571.   while(1) {
  572.     k = down1(level, is);
  573.     if(nextop(opstr)) {
  574.       bump(opsize);
  575.       if(droplab == 0) droplab = getlabel();
  576.       dropout(k, tcode, droplab, is);
  577.       }
  578.     else if(droplab) {
  579.       dropout(k, tcode, droplab, is);
  580.       gen(GETw1n, endval);
  581.       gen(JMPm, endlab = getlabel());
  582.       gen(LABm, droplab);
  583.       gen(GETw1n, dropval);
  584.       gen(LABm, endlab);
  585.       is[TI] = is[TA] = is[TC] = is[CV] = is[SA] = 0;
  586.       return 0;
  587.       }
  588.     else return k;
  589.     }
  590.   }
  591.  
  592. /*
  593. ** test for early dropout from || or && sequences
  594. */
  595. dropout(k, tcode, exit1, is)
  596.   int k, tcode, exit1, is[]; {
  597.   if(k) fetch(is);
  598.   else if(is[TC]) gen(GETw1n, is[CV]);
  599.   gen(tcode, exit1);          /* jumps on false */
  600.   } 
  601.  
  602. /*
  603. ** drop to a lower level
  604. */
  605. down(opstr, opoff, level, is)
  606.   char *opstr;  int opoff, (*level)(), is[]; {
  607.   int k;
  608.   k = down1(level, is);
  609.   if(nextop(opstr) == 0) return k;
  610.   if(k) fetch(is);
  611.   while(1) {
  612.     if(nextop(opstr)) {
  613.       int is2[7];     /* allocate only if needed */
  614.       bump(opsize);
  615.       opindex += opoff;
  616.       down2(op[opindex], op2[opindex], level, is, is2);
  617.       }
  618.     else return 0;
  619.     }
  620.   }
  621.  
  622. /*
  623. ** unary drop to a lower level
  624. */
  625. down1(level, is) int (*level)(), is[]; {
  626.   int k, *before, *start;
  627.   setstage(&before, &start);
  628.   k = (*level)(is);
  629.   if(is[TC]) clearstage(before, 0);  /* load constant later */
  630.   return k;
  631.   }
  632.  
  633. /*
  634. ** binary drop to a lower level
  635. */
  636. down2(oper, oper2, level, is, is2)
  637.   int oper, oper2, (*level)(), is[], is2[]; {
  638.   int *before, *start;
  639.   char *ptr;
  640.   setstage(&before, &start);
  641.   is[SA] = 0;                     /* not "... op 0" syntax */
  642.   if(is[TC]) {                    /* consant op unknown */
  643.     if(down1(level, is2)) fetch(is2);
  644.     if(is[CV] == 0) is[SA] = snext;
  645.     gen(GETw2n, is[CV] << double(oper, is2, is));
  646.     }
  647.   else {                          /* variable op unknown */
  648.     gen(PUSH1, 0);                /* at start in the buffer */
  649.     if(down1(level, is2)) fetch(is2);
  650.     if(is2[TC]) {                 /* variable op constant */
  651.       if(is2[CV] == 0) is[SA] = start;
  652.       csp += BPW;                 /* adjust stack and */
  653.       clearstage(before, 0);      /* discard the PUSH */
  654.       if(oper == ADD12) {         /* commutative */
  655.         gen(GETw2n, is2[CV] << double(oper, is, is2));
  656.         }
  657.       else {                      /* non-commutative */
  658.         gen(MOVE21, 0);
  659.         gen(GETw1n, is2[CV] << double(oper, is, is2));
  660.         }
  661.       }
  662.     else {                        /* variable op variable */
  663.       gen(POP2, 0);
  664.       if(double(oper, is, is2)) gen(DBL1, 0);
  665.       if(double(oper, is2, is)) gen(DBL2, 0);
  666.       }
  667.     }
  668.   if(oper) {
  669.     if(nosign(is) || nosign(is2)) oper = oper2;
  670.     if(is[TC] = is[TC] & is2[TC]) {               /* constant result */
  671.       is[CV] = calc(is[CV], oper, is2[CV]);
  672.       clearstage(before, 0);  
  673.       if(is2[TC] == UINT) is[TC] = UINT;
  674.       }
  675.     else {                                        /* variable result */
  676.       gen(oper, 0);
  677.       if(oper == SUB12
  678.       && is [TA] >> 2 == BPW
  679.       && is2[TA] >> 2 == BPW) { /* difference of two word addresses */
  680.         gen(SWAP12, 0);
  681.         gen(GETw1n, 1);
  682.         gen(ASR12, 0);          /* div by 2 */
  683.         }
  684.       is[OP] = oper;            /* identify the operator */
  685.       }
  686.     if(oper == SUB12 || oper == ADD12) {
  687.       if(is[TA] && is2[TA])     /*  addr +/- addr */
  688.         is[TA] = 0;
  689.       else if(is2[TA]) {        /* value +/- addr */
  690.         is[ST] = is2[ST];
  691.         is[TI] = is2[TI];
  692.         is[TA] = is2[TA];
  693.         }
  694.       }
  695.     if(is[ST] == 0 || ((ptr = is2[ST]) && (ptr[TYPE] & UNSIGNED)))
  696.       is[ST] = is2[ST];
  697.     }
  698.   }
  699.  
  700. /*
  701. ** unsigned operand?
  702. */
  703. nosign(is) int is[]; {
  704.   char *ptr;
  705.   if(is[TA]
  706.   || is[TC] == UINT
  707.   || ((ptr = is[ST]) && (ptr[TYPE] & UNSIGNED))
  708.     ) return 1;
  709.   return 0;
  710.   }
  711.  
  712. /*
  713. ** calcualte signed constant result
  714. */
  715. calc(left, oper, right) int left, oper, right; {
  716.   switch(oper) {
  717.     case ADD12: return (left  +  right); 
  718.     case SUB12: return (left  -  right);
  719.     case MUL12: return (left  *  right); 
  720.     case DIV12: return (left  /  right);
  721.     case MOD12: return (left  %  right); 
  722.     case EQ12:  return (left  == right); 
  723.     case NE12:  return (left  != right);
  724.     case LE12:  return (left  <= right); 
  725.     case GE12:  return (left  >= right);
  726.     case LT12:  return (left  <  right); 
  727.     case GT12:  return (left  >  right);
  728.     case AND12: return (left  &  right);
  729.     case OR12:  return (left  |  right);
  730.     case XOR12: return (left  ^  right); 
  731.     case ASR12: return (left  >> right); 
  732.     case ASL12: return (left  << right);
  733.     } 
  734.   return (calc2(left, oper, right));
  735.   }
  736.  
  737. /*
  738. ** calcualte unsigned constant result
  739. */
  740. calc2(left, oper, right) unsigned left, right; int oper; {
  741.   switch(oper) {
  742.     case MUL12u: return (left  *  right); 
  743.     case DIV12u: return (left  /  right);
  744.     case MOD12u: return (left  %  right); 
  745.     case LE12u:  return (left  <= right); 
  746.     case GE12u:  return (left  >= right);
  747.     case LT12u:  return (left  <  right); 
  748.     case GT12u:  return (left  >  right);
  749.     } 
  750.   return (0);
  751.   }
  752.  
  753.